/*
 * monitorselect函数为监控一个打开的文件描述符数组fd。
 * 当文件描述符fd[i]中有输入时，程序就从fd[i]中读取信息并调用docommand函数。
 * monitorselect函数有两个参数：打开的文件描述符数组和数组中文件描述符的数量
 * 如果select或者read函数被信号中断，函数monitorselect就会重启它们
 * 当read函数遇到其他类型的错误或者文件 结束符时，monitorselect函数就会关闭相应的描述符，并将其从监控集中删除。
 * 当所有的描述符都致使错误或者文件结束符时，monitorselect函数就会返回
 */

#include <stdio.h>
#include <errno.h>
#include <string.h>
#include <unistd.h>
#include <sys/select.h>
#include <sys/types.h>
#include "restart.h"

#define BUFSIZE 1024

void docommand(char *buf, int bytesread){

}

void monitorselect(int fd[], int numfds){
    char buf[BUFSIZE];
    int bytesread, i, maxfd;
    int numnow, numready;
    fd_set readset;

    maxfd = 0;  // 设置监控的范围
    for(i=0; i<numfds; ++i){
        if(fd[i] < 0 || fd[i] >= FD_SETSIZE) return;
        if(fd[i] >= maxfd) maxfd = fd[i] + 1;
    }

    numnow = numfds;

    // 继续监控，直到一切都完成
    while(numnow > 0){
        FD_ZERO(&readset);  // 创建文件描述符掩码
        for(i=0; i<numfds; i++){
            if(fd[i] >= 0) FD_SET(fd[i], &readset);
        }

        // 使用select函数监听文件描述符
        numready = select(maxfd, &readset, NULL, NULL, NULL);
        if(numready == -1 && errno == EINTR) continue;   // 如果被信号中断，则继续制执行
        else if(numready == -1) break;

        // 找出符合要求的文件描述符
        for(i=0; (i<numfds) && (numready > 0); ++i){
            if(fd[i] == -1) continue;
            if(FD_ISSET(fd[i], &readset)){
                bytesread = r_read(fd[i], buf, BUFSIZE);
                numready--;
                if(bytesread > 0) docommand(buf, bytesread);
                else{
                    // 如果对应的文件描述符出现错误，则关闭
                    close(fd[i]);
                    fd[i] = -1;
                    numnow--;
                }
            }
        }
    }

    for(i=0; i<numfds; i++){
        if(fd[i] >= 0) close(fd[i]);
    }
}

int main(int argc, char* argv[]){

    return 0;
}